//    Copyright (C) Kherty.  All rights reserved.
using System;

namespace OpenLS.Spreadsheet.StandardAddIn.Statistics
{
    internal class ChiSquareTest
    {
        public double ChiSquare(double[] expected, double[] actual)
        {
            double sumSq = 0.0d;
            if (!IsValid(expected, actual))
                throw new ArgumentException("not positive and negative");
            for (int i = 0; i < actual.Length; i++)
            {
                double dev = (actual[i] - expected[i]);
                sumSq += dev*dev/expected[i];
            }
            return sumSq;
        }

        public static bool IsValid(double[] expected, double[] actual)
        {
            if ((expected.Length < 2) || (expected.Length != actual.Length))
                return false;
            return (!(!isPositive(expected) || !isNonNegative(actual)));
        }

        public double Test(double[] expected, double[] actual)
        {
            return Test(expected, actual, expected.Length - 1);
        }

        public double Test(double[] expected, double[] actual, double degreeOfFreedom)
        {
            ChiSquaredDistribution chiSquaredDistribution = new ChiSquaredDistribution(degreeOfFreedom);
            return 1 - chiSquaredDistribution.CumulativeProbability(
                           ChiSquare(expected, actual));
        }


        private static bool isPositive(double[] values)
        {
            for (int i = 0; i < values.Length; i++)
            {
                if (values[i] <= 0)
                {
                    return false;
                }
            }
            return true;
        }

        private static bool isNonNegative(double[] values)
        {
            for (int i = 0; i < values.Length; i++)
            {
                if (values[i] < 0)
                {
                    return false;
                }
            }
            return true;
        }
    }
}